/***************************************************************************
 *   oboe.utils.JapiController						 *
 *   Copyright (C) 2011 by Felipe Manga					*
 *   lufeboma@gmail.com							*
 *									 *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the	   *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to	*
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:						 *
 *									 *
 *   The above copyright notice and this permission notice shall be	*
 *   included in all copies or substantial portions of the Software.	   *
 *									 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,	   *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF	*
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR	 *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.					   *
 ***************************************************************************/

package oboe.utils;

import com.adobe.crypto.MD5;
import com.adobe.serialization.json.JSON;
import com.adobe.serialization.json.JSONParseError;

import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.utils.Dictionary;
import flash.utils.Proxy;
import flash.utils.flash_proxy;

import oboe.core.Oboe;

public dynamic class JapiController extends Proxy
{
private var loaders : Dictionary;
private var loaderCount : Int = 0;

public static var viewClass : Class;

public function JapiController()
{
	super();
	this.loaders = new Dictionary();
}

flash_proxy override function getProperty(name:Dynamic):Dynamic
{
	
	var lamb : Function = function( ...rest ):Void
	{
		var func : Function = rest[0] as Function;
		var req : URLRequest = new URLRequest( Oboe.flags["PARAISO"] );
		var json : String = "{\"" + name + "\":[";
		var hash : String = "";
	for( var i:Int = (func==null)?0:1; i<rest.length; ++i ){
		
		if( rest[i] is String )
		{
		json += "\"" + rest[i] + "\"";
		hash += String(rest[i]); //  + String(i);
		}
		else if( rest[i] is Boolean )
		{
		var bval:String;
		if( rest[i] ) bval = "1";
		else bval = "0";
		json += bval;
		hash += bval;
		}
		else if( rest[i] is int || rest[i] is Number || rest[i] is uint ){
		json += String(rest[i]);
		hash += String(rest[i]);
		}
		else
		{
		var val:String = JSON.encode( rest[i] ); 
		json += val;
		hash += val;
		}
		json += ",";
	}
	json += "\"" + MD5.hash( hash );
	json += "\"]}";
	
	json = "japi=" + escape(json);
	
	req.data = new URLVariables( json );
	req.method = URLRequestMethod.POST;
	var ldr : URLLoader = new URLLoader();
	ldr.addEventListener( Event.COMPLETE,
		function ( e:Event ) : Void {
		delete loaders[e.target];
		loaderCount--;
		if( func != null ){
			var str : String = URLLoader(e.target).data;
			var ret : Object = str;
			try{
			ret = JSON.decode( str )[0];
			}catch( x:JSONParseError ){
			trace( ret = x.message + "\n" + str );
			}
			func ( ret );
		}else{
			trace( "Ignoring response: ", URLLoader(e.target).data );
		}
		}
	);
	ldr.addEventListener( IOErrorEvent.IO_ERROR, 
		function ( e:Event ) : Void {
		delete loaders[e.target];
		loaderCount--;
		trace("URL Request failed.");
		if( func != null ){
			func ( null );
		}
		}
	);
	Object(ldr).loadEx( req );
	loaders[ldr] = ldr;
	loaderCount++;
	};
	return Object(lamb);
}


flash_proxy override function callProperty( name:Dynamic, ...rest ):Dynamic
{
	var func : Function = rest[0] as Function;
	var req : URLRequest = new URLRequest( Oboe.flags["PARAISO"] );
	var json : String = "{\"" + name + "\":[";
	var hash : String = "";
	for( var i:Int = (func==null)?0:1; i<rest.length; ++i ){
	
	if( rest[i] is String )
	{
		json += "\"" + rest[i] + "\"";
		hash += String(rest[i]); //  + String(i);
	}
	else if( rest[i] is Boolean )
	{
		var bval:String;
		if( rest[i] ) bval = "1";
		else bval = "0";
		json += bval;
		hash += bval;
	}
	else if( rest[i] is int || rest[i] is Number || rest[i] is uint ){
		json += String(rest[i]);
		hash += String(rest[i]);
	}
	else
	{
		var val:String = JSON.encode( rest[i] ); 
		json += val;
		hash += val;
	}
	json += ",";
	}
	json += "\"" + MD5.hash( hash );
	json += "\"]}";
	
	json = "japi=" + escape(json);
	
	req.data = new URLVariables( json );
	req.method = URLRequestMethod.POST;
	var ldr : URLLoader = new URLLoader();
	ldr.addEventListener( Event.COMPLETE,
	function ( e:Event ) : Void {
		delete loaders[e.target];
		loaderCount--;
		if( func != null ){
		var str : String = URLLoader(e.target).data;
		var ret : Object = str;
		try{
			ret = JSON.decode( str )[0];
		}catch( x:JSONParseError ){
			trace( ret = x.message + "\n" + str );
		}
		func ( ret );
		}else{
		trace( "Ignoring response: ", URLLoader(e.target).data );
		}
	}
	);
	ldr.addEventListener( IOErrorEvent.IO_ERROR, 
	function ( e:Event ) : Void {
		delete loaders[e.target];
		loaderCount--;
		trace("URL Request failed.");
		if( func != null ){
		func ( null );
		}
	}
	);
	Object(ldr).loadEx( req );
	loaders[ldr] = ldr;
	loaderCount++;
	return;
}
}